package cn.edu.stu.contorller.system;

import cn.edu.stu.bean.AjaxResult;
import cn.edu.stu.bean.MicRecord;
import cn.edu.stu.bean.MicSong;
import cn.edu.stu.manager.AsyncManager;
import cn.edu.stu.manager.factory.AsyncFactory;
import cn.edu.stu.service.ArtistService;
import cn.edu.stu.service.ConfService;
import cn.edu.stu.service.RecordService;
import cn.edu.stu.service.SongService;
import cn.edu.stu.tool.MyHttpStatus;
import cn.edu.stu.tool.UUIDUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Karl
 * @Date 2022/12/16 - 20:40
 */
@RestController()
@RequestMapping("/song")
public class SongController {

    @Autowired
    SongService songService;

    @Autowired
    ArtistService artistService;

    @Autowired
    RecordService recordService;

    @Autowired
    ConfService confService;


    /**
     * @param md5 检查是否存在该md5文件
     * @return
     */
    @PostMapping("/checkUpload")
    public AjaxResult checkUpload(@RequestParam(value = "md5") String md5,
                                  @RequestParam(value = "img", required = false) MultipartFile uploadImg,
                                  @RequestParam("songName") String songName,
                                  @RequestParam(value = "artistId", required = false) Integer artistId,
                                  @RequestParam(value = "artist") String artist,
                                  HttpServletRequest request
    ) {
        MicRecord record = new MicRecord();
        File imgFile = null;
        record.setUserId((Long) request.getAttribute("userid"));
        record.setSongName(songName);
        try {
            if (uploadImg == null || uploadImg.getSize() == 0) record.setImgPath("1.jpg");
            else {
                record.setImgPath(getImgNameWithSuffix(uploadImg.getOriginalFilename()));
            }
            if (songService.uploadSongWithMD5(md5, record, artistId, artist)) {
                //说明文件已经有了，并且已经将用户上传记录上传成功了，现在下载图片
                imgFile = downloadImg(uploadImg, record);
                AjaxResult success = AjaxResult.success("上传成功!");
//                ArrayList<Map<String, Object>> artists = new ArrayList<>();
                success.put("id", record.getSongId());
//                success.put("artists",artist);
                return success;
            } else {
                AjaxResult result = AjaxResult.error("请开始上传!");
                result.setCode(MyHttpStatus.BEGIN_UPLOAD);
                return result;
            }
        } catch (IOException ignore) {
            //下载图片异常被这捕获,把记录删除
            recordService.deleteRecord(record);
            return AjaxResult.error("接收图片失败!");
        } catch (RuntimeException r) {
            //发生错误，将图片删除
            if (imgFile != null && !imgFile.delete()) System.out.println("下载上传的文件失败删除文件" + imgFile.getName() + "失败!");
            return AjaxResult.error(r.getMessage());
        } catch (Exception e) {
            return AjaxResult.error("服务器异常!");
        }
    }

    @PostMapping("/uploadNew")
    public AjaxResult uploadSong(@RequestParam("song") MultipartFile uploadSong,
                                 @RequestParam(value = "img", required = false) MultipartFile uploadImg,
                                 @RequestParam("songName") String songName,
                                 //下面两个其中一个必须有，代码逻辑判断
                                 @RequestParam(value = "artistId", required = false) Integer artistId,
                                 @RequestParam(value = "artist") String artist,
                                 HttpServletRequest request
    ) {
        //获取上传的文件的文件夹，不存在则创建
//        String url = this.getClass().getResource(File.separator).getPath();
//        String url = this.getClass().getClassLoader().getResource("static").getFile();
        String filePath = confService.getRootPath() + confService.getFilePath();
        System.out.println("root:" + filePath);
//        new File(url+File.separator+"song").mkdirs();
//        String filePath = "mic"+File.separator+"song";
        File file = new File(filePath), imgFile = null;
        file = new File(file.getAbsolutePath());
        if (!file.exists()) {
            file.mkdirs();
        }
        MicSong song = new MicSong();
        MicRecord record = new MicRecord();
        record.setUserId((Long) request.getAttribute("userid"));
        record.setSongName(songName);
        record.setUploadTime(System.currentTimeMillis());
        //设置文件大小
        song.setSongSize(uploadSong.getSize());
        //先将两个文件down下来
        //检查是否为mp3文件,暂时命名为temp
//        file = new File("mic"+File.separator+"song"+File.separator+"temp");
        file = new File(confService.getRootPath() + confService.getFilePath() + "temp");
        file = new File(file.getAbsolutePath());
        //用户上传了封面文件，则先保存，否则默认图片0
        boolean flag = false;
        try {

            //实现上传功能
            uploadSong.transferTo(file);
            flag = true;
            imgFile = downloadImg(uploadImg, record);
        } catch (IOException e) {
            //下载失败，如有文件，删除
            if (flag && !file.delete()) System.out.println("下载上传的文件失败删除文件" + file.getName() + "失败!");
            System.out.println(e.getMessage());
            return AjaxResult.error("上传失败！");
        }
        //到这里，文件已经下下来了，名为temp和uuid,然后尝试插入到数据库中


        try {
            if (!songService.uploadSong(song, record, artistId, artist)) {
                throw new RuntimeException("上传歌曲失败!");
            }
        } catch (Exception e) {
            //获取失败，尝试将文件删除
            file.delete();
            if (imgFile != null) imgFile.delete();
            return AjaxResult.error(e.getMessage());
        }


        //插入成功，改名
//        File newFile = new File("mic"+File.separator+"song"+File.separator+song.getSongId()+".mp3");
//        newFile = new File(newFile.getAbsolutePath());
        File newFile = new File(confService.getRootPath() + confService.getFilePath() + song.getSongId() + ".mp3");
        newFile = new File(newFile.getAbsolutePath());
        if (!file.renameTo(newFile)) {
            System.out.println(file.getName() + "重命名为" + newFile.getName() + "失败！");
        }


        //启用异步任务线程去完成MD5的计算和歌曲时长的计算
        AsyncManager.me().execute(AsyncFactory.getAndCheckSongAttr(newFile.getAbsolutePath(), song, record));

        AjaxResult success = AjaxResult.success("上传成功!");
        success.put("id", record.getSongId());
        return success;
    }

    public File downloadImg(MultipartFile uploadImg, MicRecord record) throws IOException {
        File imgFile = null;
        if (uploadImg != null && uploadImg.getSize() != 0) {
            if (record.getImgPath() == null) {
                record.setImgPath(getImgNameWithSuffix(uploadImg.getOriginalFilename()));
            }

//            imgFile = new File("mic"+File.separator+"song"+File.separator+record.getImgPath()+".jpg");
            imgFile = new File(confService.getRootPath() + confService.getFilePath() + record.getImgPath());
            System.out.println(imgFile);
            imgFile = new File(imgFile.getAbsolutePath());
            uploadImg.transferTo(imgFile);
        } else {
            record.setImgPath("1.jpg");
        }
        return imgFile;
    }

    //返回诸如.png .jpg等
    public String getImgNameWithSuffix(String imgName) {
        int idx = -1;
        if (imgName != null && (idx = imgName.lastIndexOf('.')) != -1) {
            imgName = UUIDUtil.getUUID() + imgName.substring(idx);
        } else {
            imgName = UUIDUtil.getUUID() + ".jpg";
        }
        return imgName;
    }

    @RequestMapping("/selectAll")
    public AjaxResult searchAllById(HttpServletRequest request,
                                    @RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                                    @RequestParam(value = "pageSize",defaultValue = "10") int pageSize,
                                    @RequestParam(value = "pageToShow",defaultValue = "5")int pageToShow
                                    ) {
        long uid = (long) request.getAttribute("userid");
        PageInfo<Map<String, Object>> pageInfo = recordService.selectByUidWithPage(uid, pageNum, pageSize, pageToShow);
        return AjaxResult.success("操作成功",pageInfo);
    }

    @RequestMapping("/search")
    public AjaxResult searchByFuzzyName(@RequestParam("like") String name,
                                        @RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                                        @RequestParam(value = "pageSize",defaultValue = "10") int pageSize,
                                        @RequestParam(value = "pageToShow",defaultValue = "5")int pageToShow
    ) {
        if (name.length() == 0) return AjaxResult.error("请输入搜索词！");
        PageInfo<Map<String, Object>> pageInfo = recordService.searchByFuzzyName(name, pageNum, pageSize, pageToShow);

        return AjaxResult.success("操作成功！", pageInfo);
    }

    @RequestMapping("/select")
    public AjaxResult selectAllRecord(@RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                                      @RequestParam(value = "pageSize",defaultValue = "10") int pageSize,
                                      @RequestParam(value = "pageToShow",defaultValue = "5")int pageToShow
    ){
        PageInfo<Map<String, Object>> pageInfo = recordService.selectAll(pageNum,pageSize,pageToShow);
        return AjaxResult.success("操作成功",pageInfo);
    }

    @RequestMapping("/delete/{id}")
    public AjaxResult deleteRecord(@PathVariable("id") Integer songId,
                                   HttpServletRequest request){
        Long userId = (Long) request.getAttribute("userid");
        AjaxResult result = recordService.deleteRecordBySongId(songId, userId);
        if(result.getCode()==1){
            //启用异步线程去完成检查是否需要删除该歌曲文件
            AsyncManager.me().execute(AsyncFactory.checkDeleteSongFile(songId));
        }

        return result;
    }


}
